#include "ipcd.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> // variable argument lists
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>

#include <sys/mman.h> // POSIX shared memory
#include <semaphore.h>
#include <fcntl.h> // for O_CREAT
#include <errno.h>


#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <time.h>

void log_message(char *filename, const char* format, ...) {
	FILE *logfile;
	logfile = fopen(filename, "a");
	if (!logfile) return;
	va_list list;
	va_start( list, format );
	vfprintf(logfile, format, list);
	va_end( list );
	fprintf(logfile, "\n");
    fclose(logfile);
}


int fibonacci(int n)
{
        if (n <= 1) {
        return n;
    } else {
        return fibonacci(n-1)+fibonacci(n-2);
    }
}

int main(int argc, char *argv[]) {


 key_t  key;   /* key to be passed to shmget() */
 //int  shmflg;   /* shmflg to be passed to shmget() */
 int  shmid;   /* return value from shmget() */
 //int  size;   /* size to be passed to shmget() */

 //char c;
 shmseg_t *shm;
 sem_t *signal_in, *signal_out;

	fprintf(stdout, "Hello World!\n");

        /* Our process ID and Session ID */
        pid_t pid, sid;
        char  *fname = {0};
        //time_t seconds,ref;
        fname =(char *)malloc((strlen("logtest")+1)*sizeof(char));
        strcpy(fname,"logtest");
        /* Fork off the parent process */
        pid = fork();

        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);
                
        /* Open any logs here */        
                
        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }
        

        
        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }
        
        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        
 
//------------------------------------------------------------------------------------------

        /*
         * We'll name our shared memory segment
         * "5678".
         */
        log_message(fname ,"set-go!!");

        key = 5678;

        /*
         * Create the segment.
         */
        if ((shmid = shmget(key, sizeof(shmseg_t), IPC_CREAT | 0666)) < 0) {
            log_message(fname ,"shmget.. error ");
            exit(1);
        }

log_message(fname ,"pass!!");
        //ftruncate(shmid,sizeof(shmseg_t)) ;
        /*
         * Now we attach the segment to our data space.
         */
        if ((shm = shmat(shmid, NULL, 0)) == (shmseg_t *) -1) {
            log_message(fname ,"shmmat.. error ");
            exit(1);
        }




                    if ( (signal_in = sem_open(SEMAPHORE_INPUT, O_CREAT | O_EXCL, 0666,0)) == SEM_FAILED )
                    {
                            log_message(fname ,"Error sem_open");
                            //exit(1);
                    }
                    log_message(fname,"opened semaphore: %p", signal_in);
                    if ( (signal_out = sem_open(SEMAPHORE_OUTPUT, O_CREAT | O_EXCL, 0666,0)) == SEM_FAILED )
                    {
                            log_message(fname ,"Error sem_open");
                            //exit(1);
                    }


                    while (1)
                    {
                            if ( sem_wait(signal_in)==-1)
                            {
                                    log_message(fname ,"Error sem_wait... %d, %s", errno, strerror(errno));
                                  //  exit(1);
                            }

                            log_message(fname ,"input data received, n =%d", (*shm).n);
                            (*shm).fibonacci = fibonacci((*shm).n);
                            log_message(fname,"result fibonacci =%d", (*shm).fibonacci);
                            sem_post(signal_out);
                            log_message(fname,"semaphore wait n");
                    }


                       exit(EXIT_SUCCESS);
}



